var tetris_canvas;
var tetris_ctx;
var currentFall;
var curScore,maxScore,curSpeed;
var curScoreEle,curSpeedEle,maxScoreEle;
var TETRES_ROWS=20;
var TETRES_COLS=16;
var TETRES_SIZE=30;
var NO_BLOCK=0;
var isPlaying=true;
var curTimer;
var colors=['white','red','gray','blue','purple','orange','green','brown']

function width(){                                                           //自定义宽度
    var div=document.querySelector('.big');
    div.style.width=TETRES_COLS*TETRES_SIZE+'px';
}

var CreateCanvas =function(rows,cols,cellWidth,cellHight){
    tetris_canvas=document.createElement("canvas");
    //设置canvas组件的宽、高度
    tetris_canvas.width=cols*cellWidth;
    tetris_canvas.height=rows*cellHight;
    //设置canvas组件的边框
    tetris_canvas.style.border="1px solid black";
    //获取canvas上的绘图api
    tetris_ctx=tetris_canvas.getContext('2d');
    //创建路径
    tetris_ctx.beginPath();
    //绘制横向网络对应的路径
    for(var i=1;i<TETRES_ROWS;i++)
    {
        tetris_ctx.moveTo(0,i*TETRES_SIZE);
        tetris_ctx.lineTo(TETRES_COLS*TETRES_SIZE,i*TETRES_SIZE);
    }
    
    //绘制纵向网络对应的路径
    for(var i=1;i<TETRES_COLS;i++)
    {
        tetris_ctx.moveTo(i*TETRES_SIZE,0);
        tetris_ctx.lineTo(i*TETRES_SIZE,TETRES_ROWS*TETRES_SIZE);
    }
    tetris_ctx.closePath();
    //设置笔触颜色
    tetris_ctx.strokeStyle="#aaa";
    //设置线条粗细
    tetris_ctx.lineWidth=0.3;
    //绘制线条
    tetris_ctx.stroke();

}

//定义可能出现的方块组合
var blockArr=[
    //z
    [
        {x:TETRES_COLS/2-1,y:0,color:1},
        {x:TETRES_COLS/2,y:0,color:1},
        {x:TETRES_COLS/2,y:1,color:1},
        {x:TETRES_COLS/2+1,y:1,color:1}
    ],
    //反z
    [
        {x:TETRES_COLS/2+1,y:0,color:2},
        {x:TETRES_COLS/2,y:0,color:2},
        {x:TETRES_COLS/2,y:1,color:2},
        {x:TETRES_COLS/2-1,y:1,color:2}
    ],
    //田
    [
        {x:TETRES_COLS/2-1,y:0,color:3},
        {x:TETRES_COLS/2,y:0,color:3},
        {x:TETRES_COLS/2-1,y:1,color:3},
        {x:TETRES_COLS/2,y:1,color:3}
    ],
    //L
    [
        {x:TETRES_COLS/2-1,y:0,color:4},
        {x:TETRES_COLS/2-1,y:1,color:4},
        {x:TETRES_COLS/2-1,y:2,color:4},
        {x:TETRES_COLS/2,y:2,color:4}
    ],
    //J
    [
        {x:TETRES_COLS/2,y:0,color:5},
        {x:TETRES_COLS/2,y:1,color:5},
        {x:TETRES_COLS/2,y:2,color:5},
        {x:TETRES_COLS/2-1,y:2,color:5}
    ],
    //l
    [
        {x:TETRES_COLS/2,y:0,color:6},
        {x:TETRES_COLS/2,y:1,color:6},
        {x:TETRES_COLS/2,y:2,color:6},
        {x:TETRES_COLS/2,y:3,color:6}
    ],
    //倒T
    [
        {x:TETRES_COLS/2,y:0,color:7},
        {x:TETRES_COLS/2-1,y:1,color:7},
        {x:TETRES_COLS/2,y:1,color:7},
        {x:TETRES_COLS/2+1,y:1,color:7}
    ]
]

//该数组用于记录底下已经固定的方块
var tetris_status=[];
for(var i=0;i<TETRES_ROWS;i++)
{
    tetris_status[i]=[];
    for(var j=0;j<TETRES_COLS;j++)
    {
        tetris_status[i][j]=NO_BLOCK;
    }
}

//定义初始化正在掉落的方块
var initBlock=function()
{
    var rand=Math.floor(Math.random()*blockArr.length);
    currentFall=[
        {
            x:blockArr[rand][0].x,y:blockArr[rand][0].y,color:blockArr[rand][0].color
        },
        {
            x:blockArr[rand][1].x,y:blockArr[rand][1].y,color:blockArr[rand][1].color
        },
        {
            x:blockArr[rand][2].x,y:blockArr[rand][2].y,color:blockArr[rand][2].color
        },
        {
            x:blockArr[rand][3].x,y:blockArr[rand][3].y,color:blockArr[rand][3].color
        }
    ];
}

//绘制俄罗斯方块状态
var drawBlock=function()
{
    for(var i=0;i<TETRES_ROWS;i++)
    {
        for(var j=0;j<TETRES_COLS;j++)
        {
            //有方块绘制颜色
            if(tetris_status[i][j]!=NO_BLOCK)
            {
                tetris_ctx.fillStyle=colors[tetris_status[i][j]];
                tetris_ctx.fillRect(j*TETRES_SIZE+1,i*TETRES_SIZE+1,TETRES_SIZE-2,TETRES_SIZE-2);
            }
            //没有方块绘制白色
            else
            {
                tetris_ctx.fillStyle='white';
                tetris_ctx.fillRect(j*TETRES_SIZE+1,i*TETRES_SIZE+1,TETRES_SIZE-2,TETRES_SIZE-2);
            }
        }
    }
}

//控制方块向下掉
var moveDown=function()
{
    //定义能否下落的标志
    var canDown=true;
    //遍历每个方块，判断是否能下落
    for(var i=0;i<currentFall.length;i++)
    {
        //判断是否已经到最底下
        if(currentFall[i].y>=TETRES_ROWS-1)
        {
            canDown=false;
            break;
        }
        //判断下一格是否有方块，如果有就不掉落
        if(tetris_status[currentFall[i].y+1][currentFall[i].x]!=NO_BLOCK)
        {
            canDown=false;
            break;
        }
    }
    //如果能向下掉落
    if(canDown)
    {
        //将下移前的每个方块涂成白色
        for(var i=0;i<currentFall.length;i++)
        {
            var cur=currentFall[i];
            //设置填充颜色
            tetris_ctx.fillStyle='white';
            //绘制矩形
            tetris_ctx.fillRect(cur.x*TETRES_SIZE+1,cur.y*TETRES_SIZE+1,TETRES_SIZE-2,TETRES_SIZE-2);
        }
        //将所有方块y坐标加1
        for(var i=0;i<currentFall.length;i++)
        {
            var cur=currentFall[i];
            cur.y++;
        }
        //将下移方块背景色涂色
        for(var i=0;i<currentFall.length;i++)
        {
            var cur=currentFall[i];
            //设置填充颜色
            tetris_ctx.fillStyle=colors[cur.color];
            //绘制矩形
            tetris_ctx.fillRect(cur.x*TETRES_SIZE+1,cur.y*TETRES_SIZE+1,TETRES_SIZE-2,TETRES_SIZE-2);
        }
    }
    else
    {
        //遍历每个方块，把每个方块的值记录到数组中
        for(var i=0;i<currentFall.length;i++)
        {
            var cur=currentFall[i];
            if(cur.y<2)
            {
                //清空积分值、游戏状态、当前速度
                localStorage.removeItem("curScore");
                localStorage.removeItem("tetris_status");
                localStorage.removeItem("curSpeed");
                // alert('游戏结束，请大侠重新来过');
                if(confirm("您已经输了，是否参加排名"))
                {
                    //读取maxscore记录
                    maxScore=localStorage.getItem("maxScore");
                    maxScore=maxScore==null?0:maxScore;
                    //如果当前积分大于最高积分
                    if(curScore>=maxScore)
                    {
                        //记录最高积分
                        localStorage.setItem("maxScore",curScore);
                    }
                }
                //游戏结束
                isPlaying=false;
                //清除计时器
                clearInterval(curTimer);
                return;
            }
            //把每个方块当前所在位置赋为当前方块颜色值
            tetris_status[cur.y][cur.x]=cur.color;
        }
        //判断是否有可消除的行
        lineFull();
        //记录俄罗斯方块状态
        localStorage.setItem("tetris_status",JSON.stringify(tetris_status));
        //开始一组新方块
        initBlock();
    }
}

//定义左移函数
var moveLeft=function()
{
    //能否左移
    var canLeft=true;
    for(var i=0;i<currentFall.length;i++)
    {
        //如果已经到了最左边
        if(currentFall[i].x<=0)
        {
            canLeft=false;
            break;
        }
        //左边已有方块，不能左移
        if(tetris_status[currentFall[i].y][currentFall[i].x-1]!=NO_BLOCK)
        {   
            canLeft=false;
            break;
        }
    }
    //能左移
    if(canLeft)
    {
        //将左移前的每个方块涂成白色
        for(var i=0;i<currentFall.length;i++)
        {
            var cur=currentFall[i];
            //设置填充颜色
            tetris_ctx.fillStyle='white';
            //绘制矩形
            tetris_ctx.fillRect(cur.x*TETRES_SIZE+1,cur.y*TETRES_SIZE+1,TETRES_SIZE-2,TETRES_SIZE-2);
        }
        //左移所有正在掉落的方块
        for(var i=0;i<currentFall.length;i++)
        {
            var cur=currentFall[i];
            cur.x--;
        }
        //将左移方块背景色涂色
        for(var i=0;i<currentFall.length;i++)
        {
            var cur=currentFall[i];
            //设置填充颜色
            tetris_ctx.fillStyle=colors[cur.color];
            //绘制矩形
            tetris_ctx.fillRect(cur.x*TETRES_SIZE+1,cur.y*TETRES_SIZE+1,TETRES_SIZE-2,TETRES_SIZE-2);
        }
    }
}

//定义右移函数
var moveRight=function()
{
    //能否右移
    var canRight=true;
    for(var i=0;i<currentFall.length;i++)
    {
        //如果已经到了最右边
        if(currentFall[i].x>=TETRES_COLS-1)
        {
            canRight=false;
            break;
        }
        //右边已有方块，不能右移
        if(tetris_status[currentFall[i].y][currentFall[i].x+1]!=NO_BLOCK)
        {
            canRight=false;
            break;
        }
    }
    //能右移
    if(canRight)
    {
        //将右移前的每个方块涂成白色
        for(var i=0;i<currentFall.length;i++)
        {
            var cur=currentFall[i];
            //设置填充颜色
            tetris_ctx.fillStyle='white';
            //绘制矩形
            tetris_ctx.fillRect(cur.x*TETRES_SIZE+1,cur.y*TETRES_SIZE+1,TETRES_SIZE-2,TETRES_SIZE-2);
        }
        //右移所有正在掉落的方块
        for(var i=0;i<currentFall.length;i++)
        {
            var cur=currentFall[i];
            cur.x++;
        }
        //将右移方块背景色涂色
        for(var i=0;i<currentFall.length;i++)
        {
            var cur=currentFall[i];
            //设置填充颜色
            tetris_ctx.fillStyle=colors[cur.color];
            //绘制矩形
            tetris_ctx.fillRect(cur.x*TETRES_SIZE+1,cur.y*TETRES_SIZE+1,TETRES_SIZE-2,TETRES_SIZE-2);
        }
    }
}

//定义旋转方块函数
var rorate=function()
{
    //定义能否旋转的旗标
    var canRorate=true;
    for(var i=0;i<currentFall.length;i++)
    {
        var prex=currentFall[i].x;
        var prey=currentFall[i].y;
        //始终以第三个方块为旋转中心
        //当i=2时，说明是旋转中心
        if(i!=2)
        {
            //计算方块旋转后x、y坐标
            var afterRotatex=currentFall[2].x+prey-currentFall[2].y;
            var afterRotatey=currentFall[2].y-prex+currentFall[2].x;
            //如果旋转后所在位置已有方块，则表明不能旋转
            if(tetris_status[afterRotatey][afterRotatex]!=NO_BLOCK)
            {
                canRorate=false;
                break;
            }
            //旋转坐标超出左边界
            if(afterRotatex <0||tetris_status[afterRotatey-1][afterRotatex]!=NO_BLOCK)
            {
                moveRight();
                afterRotatex=currentFall[2].x+prey-currentFall[2].y;
                afterRotatey=currentFall[2].y-prex+currentFall[2].x;
                break;
            }
            if(afterRotatex <0||tetris_status[afterRotatey-1][afterRotatex]!=NO_BLOCK)
            {
                moveRight();
                break;
            }
            //旋转坐标超出右边界
            if(afterRotatex >=TETRES_COLS-1||tetris_status[afterRotatey][afterRotatex+1]!=NO_BLOCK)
            {
                moveLeft();
                afterRotatex=currentFall[2].x+prey-currentFall[2].y;
                afterRotatey=currentFall[2].y-prex+currentFall[2].x;
                break;
            }
            if(afterRotatex >=TETRES_COLS-1||tetris_status[afterRotatey][afterRotatex+1]!=NO_BLOCK)
            {
                moveLeft();
                break;
            }
        }
    }
    //如果能旋转
    if(canRorate)
    {
        //将旋转前方块背景色涂成白色
        for(var i=0;i<currentFall.length;i++)
        {
            var cur=currentFall[i];
            //设置填充颜色
            tetris_ctx.fillStyle='white';
            //绘制矩形
            tetris_ctx.fillRect(cur.x*TETRES_SIZE+1,cur.y*TETRES_SIZE+1,TETRES_SIZE-2,TETRES_SIZE-2);
        }
        for(var i=0;i<currentFall.length;i++)
        {
            var prex=currentFall[i].x;
            var prey=currentFall[i].y;
            //始终以第三个方块为旋转中心
            //当i=2时，说明是旋转中心
            if(i!=2)
            {
                currentFall[i].x=currentFall[2].x+prey-currentFall[2].y;
                currentFall[i].y=currentFall[2].y-prex+currentFall[2].x;
            }
        }
        //将旋转后方块背景涂色
        for(var i=0;i<currentFall.length;i++)
        {
            var cur=currentFall[i];
             //设置填充颜色
             tetris_ctx.fillStyle=colors[cur.color];
             //绘制矩形
             tetris_ctx.fillRect(cur.x*TETRES_SIZE+1,cur.y*TETRES_SIZE+1,TETRES_SIZE-2,TETRES_SIZE-2);
        }
    }
}

//判断是否已满
var lineFull=function()
{
    //遍历每行
    for(var i=0;i<TETRES_ROWS;i++)
    {
        var flag=true;
        //遍历每个单元格
        for(var j=0;j<TETRES_COLS;j++)
        {
            if(tetris_status[i][j]==NO_BLOCK)
            {
                flag=false;
                break;
            }
        }
            //已有方块
            if(flag)
            {
                //将当前积分增加100
                curScoreEle.innerHTML=curScore+=100;
                //记录当前积分
                localStorage.setItem("curScore",curScore);
                //如果当前积分达到升级极限
                if(curScore>=curSpeed*curSpeed*500)
                {
                    curSpeedEle.innerHTML=curSpeed+=1;
                    //记录speed
                    localStorage.setItem("curSpeed",curSpeed);
                    clearInterval(curTimer);
                    curTimer=setInterval("moveDown();",500/curSpeed);
                }
                //把当前行下移
                for(var k=i;k>0;k--)
                {
                    for(var l=0;l<TETRES_COLS;l++)
                    {
                        tetris_status[k][l]=tetris_status[k-1][l];
                    }
                }
            }
            //消除后重新绘制
            drawBlock();    
    }
}

function start(){
    //清空积分值、游戏状态、当前速度
    localStorage.removeItem("curScore");
    localStorage.removeItem("tetris_status");
    localStorage.removeItem("curSpeed");
   //游戏结束
   isPlaying=false;
   //清除计时器
   clearInterval(curTimer);
   for(var i=0;i<TETRES_ROWS;i++)
    {
        tetris_status[i]=[];
        for(var j=0;j<TETRES_COLS;j++)
        {
            tetris_status[i][j]=NO_BLOCK;
        }
    }

    //读取localstorage里的记录
    var tmpStatus=localStorage.getItem("tetris_status");
    tetris_status=tmpStatus==null?tetris_status:JSON.parse(tmpStatus);
    
    //读取curscore记录
    curScore=localStorage.getItem("curScore");
    curScore=curScore==null?0:parseInt(curScore);
    curScoreEle.innerHTML=curScore;
    //读取maxscore记录
    maxScore=localStorage.getItem("maxScore");
    maxScore=maxScore==null?0:parseInt(maxScore);
    maxScoreEle.innerHTML=maxScore;
    //读取curpeed记录
    curSpeed=localStorage.getItem("curSpeed");
    curSpeed=curSpeed==null?1:parseInt(curSpeed);
    curSpeedEle.innerHTML=curSpeed;

    //把方块状态描绘出来
    drawBlock();
    // //初始化正在掉落的方块
    initBlock();
    // //控制每隔固定时间执行一次掉落
    curTimer=setInterval("moveDown()",500/curSpeed);
    isPlaying=true;
    return;
}

//为窗口的按键事件绑定事件监听器
window.onkeydown=function(evt)
{
    switch(evt.keyCode)
    {
        //向左
        case 37:
            if(!isPlaying)
                return;
            moveLeft();
            break;
        //向右
        case 39:
            if(!isPlaying)
                return;
            moveRight();
            break;
        //向下
        case 40:
            if(!isPlaying)
                return;
            moveDown();
            break;
        //向上
        case 38:
            if(!isPlaying)
                return;
            rorate();
            break;
        //暂停
        case 32:
            isPlaying=!isPlaying;
            if(isPlaying)
                curTimer=setInterval("moveDown();",500/curSpeed);
            else
                clearInterval(curTimer);
            break;
    }
}

window.onload=function(){
    //宽度
    width();

    //创建canvas组件
    CreateCanvas(TETRES_ROWS,TETRES_COLS,TETRES_SIZE,TETRES_SIZE);
    document.body.appendChild(tetris_canvas);
    curScoreEle=document.getElementById("CurrentScore");
    curSpeedEle=document.getElementById("Speed");
    maxScoreEle=document.getElementById("MaxScore");
    var p=document.getElementById("reStart");

    //重新开始
    p.onclick=start;

    //读取localstorage里的记录
    var tmpStatus=localStorage.getItem("tetris_status");
    tetris_status=tmpStatus==null?tetris_status:JSON.parse(tmpStatus);
    
    //读取curscore记录
    curScore=localStorage.getItem("curScore");
    curScore=curScore==null?0:parseInt(curScore);
    curScoreEle.innerHTML=curScore;
    //读取maxscore记录
    maxScore=localStorage.getItem("maxScore");
    maxScore=maxScore==null?0:parseInt(maxScore);
    maxScoreEle.innerHTML=maxScore;
    //读取curpeed记录
    curSpeed=localStorage.getItem("curSpeed");
    curSpeed=curSpeed==null?1:parseInt(curSpeed);
    curSpeedEle.innerHTML=curSpeed;

    //把方块状态描绘出来
    drawBlock();
    // //初始化正在掉落的方块
    initBlock();
    // //控制每隔固定时间执行一次掉落
    curTimer=setInterval("moveDown()",500/curSpeed);
}